//
//  SEChatViewController.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/8.
//

import UIKit
import SnapKit

class SEChatViewController: SEBaseViewController {
    
    private(set) var viewModel = SEChatViewModel()
    private(set) var uploadVM = SEUploadViewModel()
    
    var sendImage = UIImage()
    
    convenience init(infoViewModel: SEInquiryInfoViewModel, isFirstLoad: Bool = false) {
        self.init()
        self.viewModel = SEChatViewModel(inquiryInfo: infoViewModel.info)
        self.viewModel.isFirstLoad = isFirstLoad
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        bindViewModel()
        
        handleIMMessage()
        
        SEVoiceRecordManager.shared.delegate = self
    }
    
    override func setupUI() {
        setupSubviews()
        setupKeyboardControl()
        
        tableHeaderView.tappedHandler = { (imageView, originalUrl) in
            presentImageBrowser(imageView: imageView, originalUrl: originalUrl)
        }
    }
    
    override func setupNavBar() {
        super.setupNavBar()
        refreshIndicator.title = title
        navigationItem.titleView = refreshIndicator
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        loadData()
    }
    
    override func didBecomeActive() {
        if inCurrentVC { loadData() }
    }
    
    private func bindViewModel() {
        viewModel.decode()
        
        viewModel.updateData = { [weak self] status in
            self?.refreshIndicator.animating = false
            switch status {
            case .success:
                self?.viewModel.isFirstLoad = false
                self?.updateAllUIAfterLoadData()
            case .auth:
                self?.presentLoginViewController(selector: #selector(self?.loadData))
            case .failure:
                break
            }
            self?.isReloading = false
            self?.isEndRefreshing = true
        }
        
        viewModel.reloadTableView = { [weak self] (list, status) in
            switch status {
            case .success:
                self?.updateTableViewWithMore(list.count)
                self?.setRefreshHeader()
            case .auth:
                self?.presentLoginViewController(selector: #selector(self?.pullToLoadMore))
            case .failure:
                break
            }
            self?.msgTableView.endHeaderRefreshing()
            self?.isReloading = false
            self?.isEndRefreshing = true
        }
        
        viewModel.generateMessageIdSuccess = { [weak self] (messageType, status) in
            switch status {
            case .success:
                switch messageType {
                case .text:
                    self?.sendChatTextMessage()
                case .image:
                    self?.sendChatImageMessage(self?.sendImage)
                case .checkReport:
                    self?.sendCheckReport()
                default:
                    break
                }
            case .auth:
                self?.presentLoginViewController(selector: nil)
            case .failure:
                self?.chatActionBarView.inputTextView.text = self?.waitSendMsgContent
                self?.waitSendMsgContent = ""
            }
        }
        
        viewModel.confirmOnlineInquiryHandler = { [weak self, viewModel] status in
            switch status {
            case .success:
                self?.updateAllUIAfterLoadData()
                switch viewModel.inquiryInfo.dealStatus {
                case .confirmEnd:
                    self?.loadData()
                default:
                    break
                }
            case .auth:
                self?.presentLoginViewController(selector: nil)
            case .failure:
                break
            }
        }
        
        viewModel.updateFileAuthorizationHandler = { [weak self, viewModel] indexPath, status in
            switch status {
            case .success:
                let model = viewModel.updateFileAuthorizationMessage(indexPath: indexPath)
                self?.sendFileAuthorizeMessage(model)
                self?.msgTableView.reloadRows(at: [indexPath], with: .none)
            case .auth:
                self?.presentLoginViewController(selector: nil)
            default:
                break
            }
        }
    }
    
    private func updateTableViewWithMore(_ count: Int) {
        var contentOffset = msgTableView.contentOffset
        
        UIView.setAnimationsEnabled(false)
        msgTableView.beginUpdates()
        var heightOfNewRows: CGFloat = 0
        var indexPaths = [IndexPath]()
        for i in 1...count {
            let indexPath = IndexPath(row: i, section: 0)
            indexPaths.append(indexPath)
            
            heightOfNewRows += tableView(msgTableView, heightForRowAt: indexPath)
        }
        contentOffset.y += heightOfNewRows
        
        msgTableView.insertRows(at: indexPaths, with: .none)
        msgTableView.endUpdates()
        UIView.setAnimationsEnabled(true)
        
        msgTableView.setContentOffset(contentOffset, animated: false)
    }
    
    // MARK: - UI getter
    
    lazy var msgTableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .plain)
        tableView.isHidden = true
        tableView.backgroundColor = .background
        tableView.separatorStyle = .none
        tableView.contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        tableView.estimatedRowHeight = 0
        tableView.estimatedSectionHeaderHeight = 0
        tableView.estimatedSectionFooterHeight = 0
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(hideAllKeyboard))
        tapGesture.cancelsTouchesInView = false
        tapGesture.delegate = self
        tableView.addGestureRecognizer(tapGesture)
        
        tableView.register(SEChatStartEndCell.nibForCell(),
                           forCellReuseIdentifier: SEChatStartEndCell.reuseIdentifier())
        tableView.register(SEChatTextCell.nibForCell(),
                           forCellReuseIdentifier: SEChatTextCell.reuseIdentifier())
        tableView.register(SEChatImageCell.nibForCell(),
                           forCellReuseIdentifier: SEChatImageCell.reuseIdentifier())
        tableView.register(SEChatTimeCell.nibForCell(),
                           forCellReuseIdentifier: SEChatTimeCell.reuseIdentifier())
        tableView.register(SEChatConfirmEndCell.nibForCell(),
                           forCellReuseIdentifier: SEChatConfirmEndCell.reuseIdentifier())
        tableView.register(SEChatPrescriptionCell.nibForCell(),
                           forCellReuseIdentifier: SEChatPrescriptionCell.reuseIdentifier())
        tableView.register(SEChatCheckReportCell.nibForCell(),
                           forCellReuseIdentifier: SEChatCheckReportCell.reuseIdentifier())
        tableView.register(SEChatFileAuthorizeCell.nibForCell(),
                           forCellReuseIdentifier: SEChatFileAuthorizeCell.reuseIdentifier())
        
        return tableView
    }()
    
    lazy var chatActionBarView: SEChatActionBarView = {
        let actionBar = UINib.loadViewFrom(SEChatActionBarView.self)
        actionBar.delegate = self
        actionBar.inputTextView.delegate = self
        return actionBar
    }()
    
    lazy var countdownTimeView = UINib.loadViewFrom(SEChatCountdownTimeView.self)
    
    lazy var chatMoreView: SEChatMoreView = {
        let moreView = UINib.loadViewFrom(SEChatMoreView.self)
        moreView.delegate = self
        return moreView
    }()
    
    lazy var tableHeaderView = UINib.loadViewFrom(SEChatInquiryInfoHeader.self)
    
    lazy var voiceIndicatorView = UINib.loadViewFrom(SEChatVoiceIndicatorView.self)
    
    lazy var refreshIndicator = SERefreshIndicator(frame: CGRect(x: 0, y: 0, width: 200, height: 44))
    
    var imagePicker: UIImagePickerController?
    
    var actionBarPaddingBottomConstranit: Constraint?
    var keyboardHeightConstraint: NSLayoutConstraint?
    
    // MARK: - properties
    
    var messageType: SEChatMessageType = .text
    
    var waitSendMsgContent: String = ""
    
    /// 控制滑动取消后的结果，决定停止录音还是取消录音
    var finishRecording: Bool = true
    
    /// UITableView 是否正在加载数据, 如果是，把当前发送的消息缓存起来后再进行发送
    var isReloading: Bool = false
    
    /// 是否结束了下拉加载更多
    var isEndRefreshing: Bool = true
    
    var isImageUploading = false
}
